package com.zeei.ems.base.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.AxisFault;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import org.apache.axis2.transport.http.HTTPConstants;

import com.alibaba.fastjson.JSON;

public class HttpServiceUtil {
    private EndpointReference targetEPR = null;
    private String serviceNamespace = StringUtil.empty();

    public HttpServiceUtil() {
        String serviceUrl = PropertiesUtil.getProperty("SERVICE_URL");
        targetEPR = new EndpointReference(serviceUrl);
        serviceNamespace = PropertiesUtil.getProperty("SERVICE_NAMESPANCE");
        serviceNamespace = serviceNamespace.trim();
    }

    public HttpServiceUtil(String namespaceKey, String urlKey) {
        String serviceUrl = PropertiesUtil.getProperty(urlKey);
        targetEPR = new EndpointReference(serviceUrl);
        serviceNamespace = PropertiesUtil.getProperty(namespaceKey);
    }

    public String invokeServiceFunc(String funcName, Map<String, Object> args) {
        String result = StringUtil.empty();

        Options options = new Options();
        options.setAction(this.serviceNamespace + funcName);
        options.setTo(this.targetEPR);
        // 设置不受限制
        options.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, true);
        options.setTimeOutInMilliSeconds(1200000L);

        ServiceClient sender = null;
        try {
            sender = new ServiceClient();
            sender.setOptions(options);
            OMFactory fac = OMAbstractFactory.getOMFactory();
            OMNamespace omNs = fac.createOMNamespace(this.serviceNamespace, "");
            OMElement method = fac.createOMElement(funcName, omNs);

            for (String argName : args.keySet()) {
                OMElement omElement = fac.createOMElement(argName, omNs);
                omElement.setText(args.get(argName).toString());
                method.addChild(omElement);
            }

            method.build();

            OMElement response = sender.sendReceive(method);
            OMElement elementReturn = response.getFirstElement();

            result = elementReturn.getText();
        } catch (AxisFault e) {
            e.printStackTrace();
            result = String.format("%s", e.getMessage());
        }

        return result;
    }

    /*
     * 查询url是否可外网访问
     */
    public static boolean isAccessUrl(String sessionId, HttpServletRequest request) {
        String url = request.getRequestURI();
        // String clientIP = request.getRemoteAddr();
        int port = request.getLocalPort();
        // 读取配置文件的端口
        String localhostPort = PropertiesUtil.getProperty("DISABLED_SERVER_PORT");
        boolean isAccess = true;
        // if (!isInnerIP(clientIP)) {
        // 若访问端口不等于配置文件中禁用端口或配置文件中禁用端口为空，则当前url可访问
        if (StringUtil.isNotEmpty(localhostPort) && port == Integer.parseInt(localhostPort)) {
            String accessUrl = CacheUtil.getCache("AccessUrlList");
            List<String> accessUrlList = new ArrayList<String>();
            if (!StringUtil.isEmpty(accessUrl)) {
                accessUrlList = JSON.parseArray(accessUrl, String.class);
            } else {
                String bfsUrl = SpringPropertiesUtils.getProperty("filePath.path");//SessionInfoUtil.getBfsUrl();
                accessUrl = HttpRequestUtil.sendPost(sessionId, bfsUrl + "/bfs/configuration/getaccessurl", "");
                if (!StringUtil.isEmpty(accessUrl)) {
                    accessUrlList = JSON.parseArray(accessUrl, String.class);
                    CacheUtil.setCache("AccessUrlList", JSON.toJSONString(accessUrlList));
                }
            }
            for (String u : accessUrlList) {
                if (url.indexOf(u) > -1) {
                    isAccess = false;
                    break;
                }
            }
        }

        return isAccess;
    }

    public static boolean isInnerIP(String ipAddress) {
        boolean isInnerIp = false;
        if ("127.0.0.1".equals(ipAddress) || "0:0:0:0:0:0:0:1".equals(ipAddress)) {
            return true;
        }
        long ipNum = getIpNum(ipAddress);
        /**
         * 私有IP：A类 10.0.0.0-10.255.255.255 B类 172.16.0.0-172.31.255.255 C类
         * 192.168.0.0-192.168.255.255 当然，还有127这个网段是环回地址
         **/
        long aBegin = getIpNum("10.0.0.0");
        long aEnd = getIpNum("10.255.255.255");
        long bBegin = getIpNum("172.16.0.0");
        long bEnd = getIpNum("172.31.255.255");
        long cBegin = getIpNum("192.168.0.0");
        long cEnd = getIpNum("192.168.255.255");
        isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd);
        return isInnerIp;
    }

    private static long getIpNum(String ipAddress) {
        String[] ip = ipAddress.split("\\.");
        long a = Integer.parseInt(ip[0]);
        long b = Integer.parseInt(ip[1]);
        long c = Integer.parseInt(ip[2]);
        long d = Integer.parseInt(ip[3]);

        long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;

        return ipNum;
    }

    private static boolean isInner(long userIp, long begin, long end) {
        return (userIp >= begin) && (userIp <= end);
    }
}
